package com.github.niefy.modules.wx.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.github.niefy.modules.wx.entity.WxMsg;
import com.github.niefy.modules.wx.service.ServiceMsgService;
import com.github.niefy.modules.wx.service.WxMsgService;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.kefu.WxMpKefuMessage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

import static com.github.niefy.modules.wx.service.MsgReplyService.logger;

@Service
public class ServiceMsgServiceImpl implements ServiceMsgService {
    @Autowired
    WxMsgService wxMsgService;
    @Autowired
    WxMpService wxMpService;

    /**
     * 发送客服文本消息
     * @param toUser 接收用户，多个需要使用 | 隔开
     * @param sendContent 文本内容
     * @return
     * @throws WxErrorException
     */
    @Override
    public Boolean sendText(String toUser, String sendContent) throws WxErrorException {
        WxMpKefuMessage msg = WxMpKefuMessage.TEXT()
                .toUser(toUser)
                .content(sendContent)
                .build();
        return sendAndSave(msg,sendContent);
    }

    /**
     * 发送图片消息
     * @param toUser
     * @param content
     * @return
     * @throws WxErrorException
     */
    @Override
    public Boolean sendImage(String toUser, JSONObject content) throws WxErrorException {
        WxMpKefuMessage msg = WxMpKefuMessage.IMAGE()
                .mediaId(content.getString("media_id"))
                .toUser(toUser)
                .build();
        return sendAndSave(msg,content);
    }

    /**
     * 发送语音消息
     * @param toUser
     * @param content
     * @return
     * @throws WxErrorException
     */
    @Override
    public Boolean sendVoice(String toUser, JSONObject content) throws WxErrorException {
        WxMpKefuMessage msg = WxMpKefuMessage.VOICE()
                .mediaId(content.getString("media_id"))
                .toUser(toUser)
                .build();
        return sendAndSave(msg,content);
    }

    /**
     * 发送视频消息
     * @param toUser
     * @param videoInfoJson
     * @return
     * @throws WxErrorException
     */
    @Override
    public Boolean sendVideo(String toUser, JSONObject videoInfoJson) throws WxErrorException {
        WxMpKefuMessage msg = WxMpKefuMessage.VIDEO()
                .mediaId(videoInfoJson.getString("media_id"))
                .thumbMediaId(videoInfoJson.getString("thumb_media_id"))
                .description(videoInfoJson.getString("description"))
                .title(videoInfoJson.getString("title"))
                .toUser(toUser)
                .build();
        return sendAndSave(msg,videoInfoJson);
    }

    /**
     * 发送音乐消息
     * @param toUser
     * @param musicInfoJson
     * @return
     * @throws WxErrorException
     */
    @Override
    public Boolean sendMusic(String toUser, JSONObject musicInfoJson) throws WxErrorException {
        WxMpKefuMessage msg = WxMpKefuMessage.MUSIC()
                .toUser(toUser)
                .title(musicInfoJson.getString("title"))
                .musicUrl(musicInfoJson.getString("music_url"))
                .hqMusicUrl(musicInfoJson.getString("hq_music_url"))
                .thumbMediaId(musicInfoJson.getString("thumb_media_id"))
                .description(musicInfoJson.getString("description"))
                .build();
        return sendAndSave(msg,musicInfoJson);
    }

    /**
     * 发送图文消息（外链）
     * @param toUser
     * @param newsInfoJson
     * @return
     * @throws WxErrorException
     */
    @Override
    public Boolean sendNews(String toUser, JSONArray newsInfoJson) throws WxErrorException {
        WxMpKefuMessage.WxArticle article = newsInfoJson.size() == 1 ? newsInfoJson.getObject(0,WxMpKefuMessage.WxArticle.class) : null;
        WxMpKefuMessage msg = WxMpKefuMessage.NEWS()
                .toUser(toUser)
                .addArticle(article)
                .build();
        return sendAndSave(msg,newsInfoJson);
    }

    /**
     * 发送图文消息
     * 注意：图文消息只能有一条内容，否则会抛出45008异常
     * @param toUser
     * @param mediaId
     * @return
     * @throws WxErrorException
     */
    @Override
    public Boolean sendMpNews(String toUser, JSONObject mediaId) throws WxErrorException {
        WxMpKefuMessage msg = WxMpKefuMessage.MPNEWS()
                .mediaId(mediaId.getString("media_id"))
                .toUser(toUser)
                .build();
        return sendAndSave(msg,mediaId);
    }

    /**
     * 发送卡片消息
     * @param toUser
     * @param cardId
     * @return
     * @throws WxErrorException
     */
    @Override
    public Boolean sendWxCard(String toUser, JSONObject cardId) throws WxErrorException {
        WxMpKefuMessage msg = WxMpKefuMessage.WXCARD()
                .cardId(cardId.getString("card_id"))
                .toUser(toUser)
                .build();
        return sendAndSave(msg,cardId);
    }

    /**
     * 发送小程序卡片消息
     * @param toUser
     * @param miniProgramInfoJson
     * @return
     * @throws WxErrorException
     */
    @Override
    public Boolean sendMiniProgram(String toUser, JSONObject miniProgramInfoJson) throws WxErrorException {
        WxMpKefuMessage msg = WxMpKefuMessage.MINIPROGRAMPAGE()
                .appId(miniProgramInfoJson.getString("app_id"))
                .thumbMediaId(miniProgramInfoJson.getString("thumb_media_id"))
                .title(miniProgramInfoJson.getString("title"))
                .pagePath(miniProgramInfoJson.getString("page_path"))
                .toUser(toUser)
                .build();
        return sendAndSave(msg,miniProgramInfoJson);
    }

    /**
     * 发送菜单消息
     * @param toUser
     * @param msgMenusJson
     * @return
     * @throws WxErrorException
     */
    @Override
    public Boolean sendMsgMenu(String toUser, JSONObject msgMenusJson) throws WxErrorException {
        List<WxMpKefuMessage.MsgMenu> menuList = JSON.parseArray(msgMenusJson.getString("list"), WxMpKefuMessage.MsgMenu.class);
        WxMpKefuMessage msg = WxMpKefuMessage.MSGMENU()
                .msgMenus(menuList)
                .headContent(msgMenusJson.getString("head_content"))
                .tailContent(msgMenusJson.getString("tail_content"))
                .toUser(toUser)
                .build();
        return sendAndSave(msg,msgMenusJson);
    }

    /**
     * 发送并保存消息记录
     * @param msg 客服消息体
     * @return
     * @throws WxErrorException
     */
    private Boolean sendAndSave(WxMpKefuMessage msg,Object content) throws WxErrorException {
        Boolean isOk = wxMpService.getKefuService().sendKefuMessage(msg);
        // 将消息记录保存起来
        JSONObject json = new JSONObject().fluentPut("content",content);
        wxMsgService.addWxMsg(WxMsg.buildOutMsg(msg.getMsgType(),msg.getToUser(),json));
        return isOk;
    }

    @Override
    public Boolean sendMsg(String msgType,String openId,Object content){
        try{
            switch (msgType){
                case "text":
                    return sendText(openId,(String) content);
                case "image":
                    return sendImage(openId,(JSONObject) content);
                case "news":
                    return sendMpNews(openId,(JSONObject) content);
                case "voice":
                    return sendVoice(openId,(JSONObject) content);
                case "video":
                    return sendVideo(openId,(JSONObject) content);
                case "music":
                    return sendMusic(openId,(JSONObject) content);
                case "news_link":
                    return sendNews(openId,(JSONArray) content);
                case "card":
                    return sendWxCard(openId,(JSONObject) content);
                case "miniApp":
                    return sendMiniProgram(openId,(JSONObject) content);
                default:
                    return false;
            }
        }catch (WxErrorException e){
            logger.error("消息类型判断异常",e);
        }
        return false;
    }
}
